Skip to content

Improved webgpu reflection example #31409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: dev
Choose a base branch
from
Draft

Improved webgpu reflection example #31409

wants to merge 7 commits into from

Conversation

mrdoob
Copy link
Owner

@mrdoob mrdoob commented Jul 14, 2025

Related issue: #31372

Description

Tried to make webgpu_reflection (current) simpler and prettier.

Screen.Recording.2025-07-14.at.4.47.41.PM_.mov

@mrdoob mrdoob added this to the r179 milestone Jul 14, 2025
mrdoob and others added 4 commits July 14, 2025 17:08
…rt, function or class

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@mrdoob
Copy link
Owner Author

mrdoob commented Jul 14, 2025

Still far from ChatGPT's suggestion 😅

image

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 14, 2025

What I liked about the original code is that it demonstrates how to animate objects from a zero scale to the intended value since it gives the impression that things grow. This can be useful with all kinds of objects. Not just vegetation but also stuff like pillars could be animated like that.

I'm okay with all updates but I would prefer to keep the initial animation and let the tree "grow".

@mrdoob
Copy link
Owner Author

mrdoob commented Jul 14, 2025

What I liked about the original code is that it demonstrates how to animate objects from a zero scale to something the intended value since it gives the impresses that things grow. This can be useful with all kinds of objects. Not just vegetation but also stuff like pillars could be animated like that.

I removed that when I added the shadow and I noticed that the objects in the shadow didn't animate.

Seemed like a foot-gun.

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 14, 2025

I see. In this case, I'm okay with the simplification. Maybe I can come up with an approach for a different or new example that works with shadows as well...

@oosmoxiecode
Copy link
Contributor

Nice! 😸
Still have the original one up here: https://oosmoxiecode.com/archive/js_webgl/recursive_tree_cubes/
Could link to that one instead of the web archive if you like.

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 14, 2025

Could link to that one instead of the web archive if you like.

Done!

BTW. I'm a huge admirer of your WebGL demos! I was so much fun to port recursive_tree_cubes to our new TSL approach 😊 .

@Mugen87 Mugen87 mentioned this pull request Jul 14, 2025
@mrdoob
Copy link
Owner Author

mrdoob commented Jul 15, 2025

@Mugen87 As a reflection example I am actually having a hard time to understand what's going on...

Could you explain these lines?

// floor
const floorUV = uv().mul( 15 );
const floorNormalOffset = texture( floorNormal, floorUV ).xy.mul( 2 ).sub( 1 ).mul( .02 );
const reflection = reflector( { resolution: 0.5 } ); // 0.5 is half of the rendering view
reflection.target.rotateX( - Math.PI / 2 );
reflection.uvNode = reflection.uvNode.add( floorNormalOffset );
scene.add( reflection.target );
const floorMaterial = new THREE.MeshPhongNodeMaterial();
floorMaterial.colorNode = texture( floorColor, floorUV ).add( reflection );
floorMaterial.normalMap = floorNormal;
floorMaterial.normalScale.set( 0.2, - 0.2 );
const floor = new THREE.Mesh( new THREE.BoxGeometry( 50, .001, 50 ), floorMaterial );
floor.receiveShadow = true;
scene.add( floor );

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 15, 2025

const reflection = reflector( { resolution: 0.5 } ); // 0.5 is half of the rendering view 
 reflection.target.rotateX( - Math.PI / 2 ); 

These lines create the reflector and align it with the floor. Notice that the reflector itself is a node object and not a 3D object like in earlier days. That allows to modify the effect with nodes and also use the reflection in subsequent node setups.

 reflection.uvNode = reflection.uvNode.add( floorNormalOffset ); 

If you remove this line, you end up with a perfect mirror that is mixed with the floor's diffuse texture. However, since the example models the reflection of a reflective tiles, a mirror like reflection would look strange. The above line adds a distortion similar to water effects by bending the uvs with a normal offset. Since the normal offset is derived from floorNormal, the resulting reflections should look convincing.

 const floorUV = uv().mul( 15 ); 
 const floorNormalOffset = texture( floorNormal, floorUV ).xy.mul( 2 ).sub( 1 ).mul( .02 ); 

The first line scales the default uvs, then we sample the floor's normal map, transfer the sampled color into the normal range and scale it down otherwise the scattering is way too strong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants